<template>
<!--  <el-container class="documentIpt_all">-->
<!--    <el-main class="documentIpt_main">-->
      <div style="width: 100vw;height: 100vh;display: flex;align-items: center;flex-direction: column">
        <div
            ref="chart_container"
            class="content_container"
            v-loading="loading"
            @dblclick="fullScreen">
          <div
              ref="chartContainer"
              class="tree-chart"
              style="width: 100%; height: 100%; overflow: auto"></div>
        </div>
        <div class="buttons-container">
          <el-button
              size="large"
              type="primary"
              class="documentIpt_btn left_btn"
              @click="downloadImage"
          >下载图谱</el-button
          >
          <el-button
              size="large"
              type="primary"
              class="documentIpt_btn right_btn"
              @click="regenerate"
          >重新生成</el-button
          >
        </div>
      </div>
<!--    </el-main>-->
<!--  </el-container>-->
</template>

<script lang="ts" setup>
// @ts-nocheck
import { onMounted, ref } from "vue";
import * as echarts from "echarts";
import axios from "axios";
import html2canvas from "html2canvas";
import { useRouter, useRoute } from "vue-router";
// 容器定义
const chartContainer = ref(null);
// 图表实例，初始化、更新用
let chartInstance = null;

const router = useRouter();
const route = useRoute();

// 工具函数，用于 processGraphData 中的节点level更新
const updateNodeLevels = (node, level) => {
  if (node.level > level) return;
  node.level = level;
  if (node.children) {
    node.children.forEach((child) => {
      updateNodeLevels(child, level + 1);
    });
  }
};

// 处理原始数据代码（重要）
const processGraphData = (data) => {
  const nodes = [];
  const links = [];
  console.log(data);
  const nodeMap = new Map();
  // 节点处理
  data.nodes.forEach((node) => {
    const processedNode = {
      id: String(node.id),
      name: node.name,
      description: node.description,
      level: 0,
      children: [],
      // parent: null,
      isCollapsed: false,
      symbolSize: 30,
      itemStyle: { color: "#5470c6" },
    };
    nodes.push(processedNode);
    nodeMap.set(String(node.id), processedNode);
  });

  // 通过Map精确获取节点引用
  data.links.forEach((link) => {
    // 强制转换source/target为字符串类型
    const sourceId = String(link.source);
    const targetId = String(link.target);

    // 从Map中获取实际节点对象（而非临时变量）
    const sourceNode = nodeMap.get(sourceId);
    const targetNode = nodeMap.get(targetId);

    if (sourceNode && targetNode) {
      sourceNode.children.push(targetNode); // 直接操作Map中的引用
      updateNodeLevels(targetNode, sourceNode.level + 1); // 处理层级
      links.push({ source: sourceId, target: targetId });
    } else {
      console.warn(`Invalid link: source=${sourceId}或target=${targetId}未找到`);
    }
  });

  // 根据层级设置不同颜色
  const colorMap = ["#5470c6", "#91cc75", "#f1c232", "#ff7f0e", "#d62728"]; // 你可以根据需要调整颜色

  nodes.forEach((node) => {
    node.symbolSize = 30 - node.level * 5; // 随着层级增加，节点变小
    node.itemStyle.color = colorMap[node.level] || "#b0b0b0"; // 设置不同层级的颜色，如果超出指定层级则使用默认颜色
  });

  console.log("222", { nodes, links });

  return { nodes, links };
};

// 初始化图表
const initChart = (graphData) => {
  console.log("chart", graphData.nodes);
  if (!chartContainer.value) return;
  // chartContainer.value.style.height = '800px' // 重新设置高度，确保容器不为 0
  // chartContainer.value.style.width = '800px' // 重新设置高度，确保容器不为 0
  chartInstance = echarts.init(chartContainer.value);

  const option = {
    tooltip: {
      formatter: (params) => {
        if (params.dataType === "node") {
          return `${params.data.name}<br/>${params.data.description || "暂无详细描述"}`;
        }
      },
    },
    series: [
      {
        type: "graph",
        layout: "force",
        data: graphData.nodes,
        links: graphData.links,
        roam: true, // 支持图表拖动
        focusNodeAdjacency: true, // 鼠标悬停时高亮邻居节点
        label: {
          show: true,
          position: "right",
          formatter: "{b}", // 显示节点名称
        },
        force: {
          repulsion: 100,
          gravity: 0.1,
          edgeLength: 50,
        },
        emphasis: {
          focus: "adjacency",
          label: {
            show: true,
          },
        },
        // 设置链接的样式
        lineStyle: {
          color: "#ccc",
          width: 3,
        },
        draggable: true, // 开启节点拖拽功能
      },
    ],
  };

  chartInstance.setOption(option);

  // 窗口自适应
  window.addEventListener("resize", () => chartInstance.resize());

  // 事件监听：点击节点折叠子节点
  chartInstance.on("click", (event) => {
    if (event.dataType === "node") {
      const clickedNodeId = event.data.id;
      toggleCollapse(clickedNodeId, graphData);
    }
  });
};

// 折叠/展开节点（仅折叠子节点）
const toggleCollapse = (nodeId, graphData) => {
  const node = graphData.nodes.find((n) => n.id === nodeId);

  if (node) {
    node.isCollapsed = !node.isCollapsed;

    // 更新节点及其连接关系
    if (node.isCollapsed) {
      // 折叠时，隐藏该节点的所有子节点，并删除与子节点的连接
      collapseNodeChildren(node, graphData);
    } else {
      // 展开时，恢复该节点的所有子节点，并恢复连接
      expandNodeChildren(node, graphData);
    }

    // 更新图谱数据
    updateGraphData(graphData);

    // 打印调试信息
    console.log("graphData after toggle:", graphData);
  }
};

// 折叠节点的子节点及其连接
const collapseNodeChildren = (node, graphData) => {
  console.log(node.children);

  if (!node.children || node.children.length === 0) return;

  // 递归折叠每个子节点
  for (let i = 0; i < node.children.length; i++) {
    const child = node.children[i];
    // if (!child.isCollapsed) {
    // 删除子节点
    graphData.nodes = graphData.nodes.filter((n) => n.id !== child.id);
    // 删除与子节点的链接
    graphData.links = graphData.links.filter(
      (link) => link.source !== child.id && link.target !== child.id
    );
    collapseNodeChildren(child, graphData); // 递归折叠子节点
    // }
  }
};

// 展开节点的子节点及其连接
const expandNodeChildren = (node, graphData) => {
  // 恢复该节点
  if (!graphData.nodes.find((n) => n.id === node.id)) {
    graphData.nodes.push(node);
  }

  // 恢复该节点的子节点及其连接
  if (node.children && node.children.length > 0) {
    for (let i = 0; i < node.children.length; i++) {
      const child = node.children[i];
      // if (!child.isCollapsed) {
      // 恢复父子节点的连接
      if (!graphData.links.some((link) => link.source === node.id && link.target === child.id)) {
        graphData.links.push({ source: node.id, target: child.id });
      }

      // 递归展开子节点
      expandNodeChildren(child, graphData);
      // }
    }
  }
};

// 更新图谱数据
const updateGraphData = (graphData) => {
  const updatedNodes = [];
  const updatedLinks = [];

  // 更新节点和链接
  graphData.nodes.forEach((node) => {
    if (!node.isCollapsed) {
      updatedNodes.push(node);
    }

    // 处理子节点的链接
    if (Array.isArray(node.children)) {
      for (let i = 0; i < node.children.length; i++) {
        const child = node.children[i];
        if (!child.isCollapsed) {
          updatedLinks.push({
            source: node.id,
            target: child.id,
          });
        } else {
          // 保留折叠节点和父节点的链接
          updatedLinks.push({
            source: node.id,
            target: child.id,
          });
        }
      }
    }
  });
  // 在更新图表时，保留折叠的节点
  graphData.nodes.forEach((node) => {
    if (node.isCollapsed && !updatedNodes.find((n) => n.id === node.id)) {
      updatedNodes.push(node); // 将折叠的节点加入
    }
  });
  console.log(updatedNodes);

  // 更新图表
  chartInstance.setOption({
    series: [
      {
        data: updatedNodes,
        links: updatedLinks,
      },
    ],
  });
};

// 处理节点id为字符串类型
const processNodeIds = (data) => {
  data.nodes.forEach((node) => {
    node.id = String(node.id); // 将id转换为字符串类型
  });
  data.links.forEach((link) => {
    link.source = String(link.source); // 将id转换为字符串类型
    link.target = String(link.target); // 将id转换为字符串类型
  });
  return data;
};

// 获取后端知识图谱的数据（nodes以及links）
const fetchData = async (id: string) => {
  try {
    const response = await axios.post(`http://111.63.183.17:5000/Graphdata?course_id=` + id, {});
    // 处理节点id为字符串类型
    const processedData = processGraphData(processNodeIds(response.data));
    // console.log('111', processedData)
    initChart(processedData);
  } catch (error) {
    console.error("数据获取失败:", error);
  }
};

const fetchDataAgain = async (id: string) => {
  try {
    const response = await axios.post(`http://111.63.183.17:5000/ResetGraph?course_id=` + id, {});
    console.log(response.data);
    // 处理节点id为字符串类型
    const processedData = processGraphData(processNodeIds(response.data));
    console.log("again", processedData);
    initChart(processedData);
  } catch (error) {
    console.error("数据获取失败:", error);
  }
};

onMounted(() => {
  // fetchData('1890678883414458369')
  const course_id = route.query.courseId; // 获取路由参数
  console.log(course_id);

  if (course_id) {
    fetchData(course_id as string); // 传递参数 id 获取数据
  }
});

// 全屏
const chart_container = ref(null);

const fullScreen = function () {
  if (chart_container.value.requestFullscreen) {
    chart_container.value.requestFullscreen();
  } else if (chart_container.value.webkitRequestFullscreen) {
    // 兼容 WebKit 浏览器
    chart_container.value.webkitRequestFullscreen();
  } else if (chart_container.value.mozRequestFullScreen) {
    // 兼容 Firefox
    chart_container.value.mozRequestFullScreen();
  }
};

// 重新生成
const regenerate = function () {
  // fetchDataAgain('1890678883414458369')
  const course_id = route.query.courseId; // 获取路由参数
  if (course_id) {
    fetchDataAgain(course_id as string); // 传递参数 id 获取数据
  }
};

// 下载图谱
const downloadImage = async function () {
  const canvas = await html2canvas(chart_container.value);
  const image = canvas.toDataURL("image/png");
  const link = document.createElement("a");
  link.href = image;
  link.download = "screenshot.png";
  link.click();
};
</script>

<style lang="less" scoped>
.content_container {
  background-color: white;
  width: 100%;
  height: 100%;
  border-radius: 10px; /* 设置圆角半径 */
  display: flex; /* 使用flex布局 */
  justify-content: center; /* 水平居中 */
  align-items: center; /* 垂直居中 */
  .tree-chart {
    height: 500px;
  }
}


.documentIpt_all {
  background-image: url(../assets/知识图谱图片2.png);
  background-size: cover;
}
.documentIpt_header {
  margin: 0 auto;
  margin-top: 1%;
  p {
    color: #ffffff;
    font-weight: 700;
    font-size: 74px;
    padding-top: 4%;
  }
}

.documentIpt_main {
  padding: 0;
  height: 100vh;
  position: relative;

 /* .content_container {
    background-color: white;
    width: 90%;
    height: 90%;
    position: absolute; !* 使用绝对定位 *!
    left: 5%;
    border-radius: 10px; !* 设置圆角半径 *!
    display: flex; !* 使用flex布局 *!
    justify-content: center; !* 水平居中 *!
    align-items: center; !* 垂直居中 *!
    .tree-chart {
      height: 500px;
    }
  }
*/
  .buttons-container {
    // display: flex;
    // justify-content: center;
    // gap: 200px; /* 添加按钮之间的间距 */
    position: absolute;
    bottom: 1vh;
    left: 38vw;
    .documentIpt_btn {
      width: 100px;
      height: 50px;
      background-color: #b49c73;
      border-color: #b49c73;
      color: black;
      font-size: 20px;
      font-weight: 800;
      margin-right: 10vw;
    }
  }
}
</style>
